import * as THREE from "three";
import * as kokomi from "kokomi.js";
import gsap from "gsap";
import type Experience from "../Experience";

/**
 * 风阻线条组件
 * 显示车身上方的气流线条，使用贝塞尔曲线实现拱形效果
 */
export default class AirflowLines extends kokomi.Component {
  declare base: Experience;
  linesGroup: THREE.Group;
  lines: THREE.Line[] = [];
  isVisible: boolean = false;

  constructor(base: Experience) {
    super(base);

    this.linesGroup = new THREE.Group();
    this.linesGroup.visible = false;
    // 向下移动组件位置
    this.linesGroup.position.y = -1.0; // 向下移动约100px（调整为合适的3D单位）
    this.createAirflowLines();
  }

  /**
   * 创建风阻线条
   */
  createAirflowLines() {
    const lineCount = 20; // 线条数量
    const carWidth = 1.8; // 车宽（不超过模型宽度）
    const spacing = carWidth / (lineCount - 1); // 线条间距

    // 车身参数
    const carFront = 2.0; // 车前位置
    const carRear = -2.5; // 车后位置
    const extensionLength = 1.5; // 前后延伸长度 - 设为0使曲线从车头位置开始
    const carHeight = 1.6; // 车顶高度
    const bumperHeight = 1.2; // 延伸段高度（向上移动约100px）
    const archHeight = 1.0; // 拱形高度（车顶上方的额外高度）- 与车身高度一致

    for (let i = 0; i < lineCount; i++) {
      // 计算当前线条的Z坐标（左右位置）
      const z = -carWidth / 2 + i * spacing;
      
      this.createSingleAirflowLine(
        carFront,
        carRear,
        z,
        extensionLength,
        carHeight,
        bumperHeight,
        archHeight
      );
    }
  }

  /**
   * 创建单条风阻线
   */
  createSingleAirflowLine(
    carFront: number,
    carRear: number,
    z: number,
    extensionLength: number,
    carHeight: number,
    bumperHeight: number,
    archHeight: number
  ) {
    // 定义控制点
    const points: THREE.Vector3[] = [];
    
    // 前方延伸段起点（保险杠高度）
    const frontStart = carFront + extensionLength;
    
    // 后方延伸段终点（保险杠高度）
    const rearEnd = carRear - extensionLength;
    
    // 车身中心点（最高点）
    const carCenter = (carFront + carRear) / 2;
    const peakHeight = carHeight + archHeight;
    
    // 使用更多点来创建平滑的贝塞尔曲线
    // 前延伸段
    const frontExtPoint1 = new THREE.Vector3(frontStart, bumperHeight, z);
    const frontExtPoint2 = new THREE.Vector3(frontStart * 0.7 + carFront * 0.3, bumperHeight + archHeight * 0.3, z);
    
    // 过渡到车身上方
    const frontTransition = new THREE.Vector3(carFront, carHeight + archHeight * 0.5, z);
    
    // 车身中央拱形最高点
    const centerPeak = new THREE.Vector3(carCenter, peakHeight, z);
    
    // 车尾过渡
    const rearTransition = new THREE.Vector3(carRear, carHeight + archHeight * 0.5, z);
    
    // 后延伸段
    const rearExtPoint1 = new THREE.Vector3(rearEnd * 0.3 + carRear * 0.7, bumperHeight + archHeight * 0.3, z);
    const rearExtPoint2 = new THREE.Vector3(rearEnd, bumperHeight, z);
    
    // 创建贝塞尔曲线
    const curve = new THREE.CatmullRomCurve3([
      frontExtPoint1,
      frontExtPoint2,
      frontTransition,
      centerPeak,
      rearTransition,
      rearExtPoint1,
      rearExtPoint2
    ], false, "catmullrom", 0.3);
    
    // 从曲线获取点
    const curvePoints = curve.getPoints(100);
    
    // 创建几何体
    const geometry = new THREE.BufferGeometry().setFromPoints(curvePoints);
    
    // 创建材质
    const material = new THREE.LineBasicMaterial({
      color: 0xffffff,
      transparent: true,
      opacity: 0,
      linewidth: 1,
    });
    
    const line = new THREE.Line(geometry, material);
    this.linesGroup.add(line);
    this.lines.push(line);
  }

  /**
   * 添加到场景或指定父对象
   */
  addExisting(parent?: THREE.Object3D) {
    if (parent) {
      parent.add(this.linesGroup);
    } else {
      this.container.add(this.linesGroup);
    }
  }

  /**
   * 显示风阻线条（带动画）
   */
  show() {
    this.isVisible = true;
    this.linesGroup.visible = true;
    
    // 为每条线创建透明度波动动画
    this.lines.forEach((line, index) => {
      const material = line.material as THREE.LineBasicMaterial;
      
      // 先快速显示到高透明度
      gsap.to(material, {
        opacity: 1.0,
        duration: 0.5,
        delay: index * 0.02,
        ease: "power2.out",
        onComplete: () => {
          // 显示完成后开始循环的透明度波动动画（0.2-1.0之间）
          gsap.to(material, {
            opacity: 0.2, // 波动到0.2
            duration: 1.5 + Math.random() * 1, // 1.5-2.5秒随机
            ease: "sine.inOut",
            yoyo: true, // 来回循环（0.2 -> 1.0 -> 0.2）
            repeat: -1, // 无限循环
            delay: Math.random() * 0.5, // 随机延迟，使线条不同步
          });
        }
      });
    });
  }

  /**
   * 隐藏风阻线条
   */
  hide() {
    this.isVisible = false;
    
    // 快速隐藏所有线条
    this.lines.forEach((line) => {
      const material = line.material as THREE.LineBasicMaterial;
      
      gsap.to(material, {
        opacity: 0,
        duration: 0.3,
        ease: "power2.in"
      });
    });
    
    // 延迟隐藏组
    setTimeout(() => {
      this.linesGroup.visible = false;
    }, 500);
  }

  /**
   * 销毁组件
   */
  destroy() {
    // 停止所有正在进行的 GSAP 动画
    this.lines.forEach((line) => {
      const material = line.material as THREE.LineBasicMaterial;
      gsap.killTweensOf(material);
    });
    
    // 释放所有几何体和材质
    this.lines.forEach((line) => {
      line.geometry.dispose();
      (line.material as THREE.Material).dispose();
    });
    
    // 清空数组和组
    this.lines = [];
    this.linesGroup.clear();
    
    // 从父对象中移除（无论是场景还是rotationGroup）
    if (this.linesGroup.parent) {
      this.linesGroup.parent.remove(this.linesGroup);
    }
    
    this.isVisible = false;
  }
}
